package com.hoe.tsb.ring;

import com.hoe.tsb.fraft.exception.FRaftException;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.util.Base64;

/**
 * <p>
 * 环签名工具类
 * </p>
 *
 * @author hoe
 * @since 2022/11/12
 */
public class RingUtils {

    /**
     * 默认的密钥对长度
     */
    private final static int KEY_SIZE = 256;

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    /**
     * 生成环签名的密钥对
     * @return 生成好的环签名密钥对
     */
    public static KeyPair genKeyPair() {
        return genKeyPair(KEY_SIZE);
    }

    /**
     * 生成环签名的密钥对
     * @param keySize 密钥对长度
     * @return 生成好的环签名密钥对
     */
    public static KeyPair genKeyPair(int keySize) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
            keyPairGenerator.initialize(keySize, new SecureRandom());
            return keyPairGenerator.generateKeyPair();
        } catch (Exception e) {
            throw new FRaftException("生成环签名密钥对错误", e);
        }
    }

    /**
     * 从环签名密钥对中提取公钥
     * @param keyPair 密钥对
     * @return 公钥
     */
    public static byte[] getPublicKey(KeyPair keyPair) {
        ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
        return publicKey.getEncoded();
    }

    /**
     * 从环签名密钥对中提取私钥
     * @param keyPair 密钥对
     * @return 私钥
     */
    public static byte[] getPrivateKey(KeyPair keyPair) {
        ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
        return privateKey.getEncoded();
    }

    /**
     * 从环签名密钥对中提取Base64编码后的公钥字符串
     * @param keyPair 密钥对
     * @return base64编码的公钥
     */
    public static String getBase64PublicKey(KeyPair keyPair) {
        byte[] bytes = getPublicKey(keyPair);
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 从环签名密钥对中提取Base64编码后的私钥字符串
     * @param keyPair 密钥对
     * @return base64编码的私钥
     */
    public static String getBse64PrivateKey(KeyPair keyPair) {
        byte[] bytes = getPrivateKey(keyPair);
        return Base64.getEncoder().encodeToString(bytes);
    }

}
